﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Windows.Forms;
using CarolLib.Control;
using CarolLib.Extension;
using CarolLib.FTP;
using CarolLib.WinService;
using DCS.Business.Manager;
using DCS.Business.Model;
using DCS.Configuration;
using DCS.DataProvider;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace DCSMonitor
{
    public partial class frmMain : Form
    {
        static MonitorManager manager;
        static DCSFileManager dcsmanager;

        public frmMain()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            IUnityContainer myContainer = new UnityContainer();
            UnityConfigurationSection section
              = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Containers["Data"].Configure(myContainer);

            IDataProvider dp = myContainer.Resolve<IDataProvider>();

            manager = new MonitorManager(dp);
            dcsmanager = new DCSFileManager(dp);

            this.timerService.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshIntrv"]) * 1000;
        }

        #region Event Handlers

        private void frmMain_Load(object sender, EventArgs e)
        {
            BindServices();
            BindDCSSummary();
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void dgvSerivces_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvSerivces.SelectedRows.Count > 0)
            {
                string serviceName = dgvSerivces.SelectedRows[0].Cells["ServiceName"].Value.ToString();
                ServiceStatus status = (ServiceStatus)dgvSerivces.SelectedRows[0].Cells["Status"].Value;
                foreach (Control item in groupBox1.Controls)
                {
                    if (item is Button)
                    {
                        item.Enabled = false;
                    }
                }

                btnOpenlocation.Enabled = true;
                switch (status)
                {
                    case ServiceStatus.NotInstalled:
                        btnInstall.Enabled = true;
                        btnDebug.Enabled = true;
                        break;
                    case ServiceStatus.Stopped:
                        btnUninstall.Enabled = true;
                        btnStart.Enabled = true;
                        btnDebug.Enabled = true;
                        break;
                    case ServiceStatus.StartPending:
                        break;
                    case ServiceStatus.StopPending:
                        break;
                    case ServiceStatus.Running:
                        btnStop.Enabled = true;
                        break;
                    case ServiceStatus.ContinuePending:
                        break;
                    case ServiceStatus.PausePending:
                        break;
                    case ServiceStatus.Paused:
                        btnStart.Enabled = true;
                        break;
                    default:
                        break;
                }
            }
        }

        private void btnServiceControl_Click(object sender, EventArgs e)
        {
            string serviceName = dgvSerivces.SelectedRows[0].Cells["ServiceName"].Value.ToString();
            string path = ServiceConfiguration.GetConfig().services.Where(s => s.ServiceName == serviceName).First().FullPath;

            int tag = (sender as Button).Tag.ToString().TryToInt();
            switch (tag)
            {
                case 1:
                    System.Diagnostics.Process.Start(path, "-start");
                    break;
                case 2:
                    System.Diagnostics.Process.Start(path, "-stop");
                    break;
                case 3:
                    System.Diagnostics.Process.Start(path, "-install");
                    break;
                case 4:
                    System.Diagnostics.Process.Start(path, "-uninstall");
                    break;
                case 5:
                    System.Diagnostics.Process.Start(path, "-debug");
                    break;
                case 6:
                    string filepath = ServiceConfiguration.GetConfig().services.Where(s => s.ServiceName == serviceName).First().Path;
                    System.Diagnostics.Process.Start("Explorer.exe", filepath);
                    break;
                default:
                    break;
            }
        }

        private void timerService_Tick(object sender, EventArgs e)
        {
            BindServices();
            if (this.cbAutoRefresh.Checked)
            {
                BindDCSSummary();
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            BindDCSSummary();
        }

        private void cbGroupByDate_CheckedChanged(object sender, EventArgs e)
        {
            BindDCSSummary();
        }

        private void btnLDMClean_Click(object sender, EventArgs e)
        {
            CleanMessageStatus("LSP");
        }

        private void btnPRLClean_Click(object sender, EventArgs e)
        {
            CleanMessageStatus("PRL");
        }

        private void btnLDMDelete_Click(object sender, EventArgs e)
        {
            DeleteCleanMessage("LSP");
        }

        private void btnPRLDelete_Click(object sender, EventArgs e)
        {
            DeleteCleanMessage("PRL");
        }

        #endregion

        #region DataBinding

        private void BindDCSSummary()
        {
            SortableBindingList<DCSFileSummary> statusList = new SortableBindingList<DCSFileSummary>(manager.GetDCSFileSummary(this.cbGroupByDate.Checked));
            dgvStatus.DataSource = statusList;
            dgvStatus.Columns["Year"].Visible = false;
            dgvStatus.Columns["Month"].Visible = false;
            dgvStatus.Columns["Day"].Visible = false;
            dgvStatus.Columns["CreateDate"].Visible = this.cbGroupByDate.Checked;
            this.lblTodayDCS.Text = statusList.Where(d => d.CreateDate == DateTime.Today).Sum(d => d.MessageCount).ToString();
            this.lblSummaryTime.Text = DateTime.Now.ToString();
        }

        private void BindServices()
        {
            List<ServiceEntity> services = ServiceConfiguration.GetConfig().services;
            services.ForEach(s => s.Status = ServiceControl.GetServiceStatus(s.ServiceName));
            dgvSerivces.DataSource = services;
            this.dgvSerivces.Refresh();
            dgvSerivces_SelectionChanged(this, new EventArgs());
        }

        private void BindDataTables()
        {

        }

        #endregion

        #region FTP Related.

        private static FTPclient GetFTPClient()
        {
            FTPclient ftp = new FTPclient("10.6.183.172", true, "mumsg", "1q2w3e4r");
            return ftp;
        }

        private static void CleanMessageStatus(string messageType)
        {
            var files = dcsmanager.GetDCSFilesByMessageType(messageType, FileStatus.FinishParse | FileStatus.FinishDownload, 1800, 0, false);

            FTPclient ftp = GetFTPClient();
            FTPdirectory serverList = ftp.ListDirectoryDetail(string.Format("/{0}/", messageType));

            foreach (var file in files)
            {
                // already deleted.
                if (serverList.Where(f => f.Filename == file.RemoteFileName).Count() == 0)
                {
                    file.Status = FileStatus.FinishClean;
                }
            }

            var list = files.Where(f => f.Status == FileStatus.FinishClean).ToList();

            dcsmanager.UpdateDCSFilesStatus(list);
        }

        private static void DeleteCleanMessage(string messageType)
        {
            var dicFiles = manager.GetRecentFileStatus(100, messageType);

            FTPclient ftp = GetFTPClient();
            FTPdirectory serverList = ftp.ListDirectoryDetail(string.Format("/{0}/", messageType));
            List<string> deletelist = new List<string>();

            FileStatus fs;
            foreach (var file in serverList)
            {
                if (dicFiles.TryGetValue(file.Filename, out fs) && ((fs & FileStatus.FinishClean) == FileStatus.FinishClean))
                {
                    deletelist.Add(file.Path + file.Filename);
                }
            }

            deletelist.ForEach(f => ftp.FtpDeleteAsyc(f));
        }

        #endregion

    }
}
